package com.smit.usbdetect;

import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Locale;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {
	UsbManager mUsbManager;
	private static final String ACTION_USB_PERMISSION = "com.smit.usbhost.USB_PERMISSION";
	private static final String TAG = "USB_Detect_20111116";
	private TextView msgText;
	private Button btnOpen;
	private Button btnStart;
	private static final int CAM_USB_VID = 8210; //1157; //
	private static final int CAM_USB_PID = 2067; //22357;
	private static final int USB_HANDLE_MSG = 1;
	PendingIntent permissionIntent;
	IntentFilter filter;
	
	public UsbEndpoint endPointIn[] = new UsbEndpoint[4];
	public UsbEndpoint endPointOut[] = new UsbEndpoint[4];
	public UsbEndpoint endPointINT = null;
	UsbDeviceConnection usbConnection = null;
	public int USBInitOk = 0;
	private int taskStart = 0;
	private byte recvBuffer[]=new byte[1000000];	
	private byte sendBuffer[]=new byte[10000];
	private Thread myUsbThread=null;
	private Handler msgHandler;
	private int grantCount = 0;
	@SuppressLint("HandlerLeak")
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
		permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(
				ACTION_USB_PERMISSION), 0);
		filter = new IntentFilter(ACTION_USB_PERMISSION);

		registerReceiver(mUsbReceiver, filter);
		registerReceiver(mUsbReceiver, new IntentFilter(
				UsbManager.ACTION_USB_DEVICE_DETACHED));

		setContentView(R.layout.activity_main);
		msgText = (TextView) findViewById(R.id.msgText);
		btnOpen = (Button) findViewById(R.id.btnOpen);
		btnStart = (Button) findViewById(R.id.btnStart);
		btnStart.setVisibility(View.GONE);
		GetUsbDeviceList();
		//handle task msg and show on textview
		msgHandler = new Handler(){
				@SuppressLint("HandlerLeak")
				@Override  
	            public void handleMessage(Message msg) {  
	                // TODO Auto-generated method stub  
	                super.handleMessage(msg);  
	                switch(msg.what){  
	                case USB_HANDLE_MSG:  
	                	//logMsg.setText("USB_HANDLE_MSG"+countTask); 
	                	Bundle data = msg.getData();
	                	LogMsg(data.getString("msg"));
	                    break;  
	                }               
	            }
		};
		// open cam usb and get permission
		btnOpen.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				msgText.setText("");
				HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
				USBInitOk = 0;
				if(deviceList.size() == 0){
					LogMsg("!!  No Device Found  !!");
					return;
				}
				LogMsg("============================================================================");
				for (UsbDevice device : deviceList.values()) { // 这个for循环根本就没有进入
					LogMsg("Device Name=" + device.getDeviceName() + " VID="
							+ device.getVendorId() + " PID="
							+ device.getProductId());
					if (device.getVendorId() == CAM_USB_VID
							&& device.getProductId() == CAM_USB_PID){
						grantCount++;
						LogMsg("检测到了CAM USB设备了!");
						LogMsg("Now start to requestPermission for CAM USB!");
						mUsbManager.requestPermission(device, permissionIntent);
						LogMsg("May No permission dialog popup for System Not Allowed request for this app!");
						if(grantCount >= 5){
							LogMsg("@@INIT CAM USB WITHOUT PERMISSSION NOW!");
							if(0 == InitUsbInterface(device)){
								LogMsg("@@Init CAM USB Failed!");
							}
						}
						LogMsg("============================================================================");
					}
					else{
						LogMsg("No need to requeset permission for this USB device!");
						LogMsg("============================================================================");
					}
				}
				LogMsg("============================================================================");
			}
		});
		// start to trans data
		btnStart.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub 
				if(taskStart == 0){//go to start the task
					LogMsg("Start Clicked and tastStart="+taskStart+" USBInitOk="+USBInitOk);
					myUsbThread = NewUSBThread();
					if(USBInitOk == 1){//cam usb is ok
						myUsbThread.start();
						taskStart = 1;
						LogMsg("myUsbThread started and tastStart="+taskStart);
						btnStart.setText("Stop");
					}
					else{//cam usb not ok
						LogMsg("myUsbThread set to null");
						myUsbThread = null;
					}
				}
				else{//go to stop the task;
					btnStart.setText("Start");
					LogMsg("Stop Clicked and tastStart="+taskStart+" USBInitOk="+USBInitOk);
					if(myUsbThread != null){
						myUsbThread.interrupt();
						LogMsg("myUsbThread interrupt");
						myUsbThread = null;
					}
					taskStart = 0;
					LogMsg("Stop Clicked to go out and tastStart="+taskStart);
				}
			}
		});

	}
	///////////
	private void GetUsbDeviceList() {
		HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
		USBInitOk = 0;
		if(deviceList.size() == 0){
			LogMsg("!!  No Device Found  !!");
			return;
		}
		LogMsg("============================================================================");
		for (UsbDevice device : deviceList.values()) { // 这个for循环根本就没有进入
			LogMsg("Device Name=" + device.getDeviceName() + " VID="
					+ device.getVendorId() + " PID="
					+ device.getProductId());
			if (device.getVendorId() == CAM_USB_VID
					&& device.getProductId() == CAM_USB_PID){
				grantCount++;
				LogMsg("<b>Now start to requestPermission for CAM USB!</b>");
				mUsbManager.requestPermission(device, permissionIntent);
				LogMsg("May No permission dialog popup for System Not Allowed request for this app!");
				if(grantCount >= 5){
					LogMsg("@@INIT CAM USB WITHOUT PERMISSSION NOW!");
					if(0 == InitUsbInterface(device)){
						LogMsg("@@Init CAM USB Failed!");
					}
				}
				LogMsg("============================================================================");
			}
			else{
				LogMsg("No need to requeset permission for this USB device!");
				LogMsg("============================================================================");
			}
		}
		LogMsg("============================================================================");
	}
	//////////
	private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {

		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			if (ACTION_USB_PERMISSION.equals(action)) {
				unregisterReceiver(mUsbReceiver);
				synchronized (this) {
					UsbDevice device = (UsbDevice) intent
							.getParcelableExtra(UsbManager.EXTRA_DEVICE);

					if (intent.getBooleanExtra(
							UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
						if (device != null) {
							// call method to set up device communication
							LogMsg("Permisson granted!! @@Device Name="
									+ device.getDeviceName() + " VID="
									+ device.getVendorId() + " PID="
									+ device.getProductId());
							grantCount = 0;
							//InitUsbInterface(device);
							//btnStart.setVisibility(View.VISIBLE);
							//btnOpen.setVisibility(View.GONE);
						}
					} else {
						LogMsg("permission denied for device " + device);
					}
				}
			}
		}
	};
	private Thread NewUSBThread(){
        return new Thread(new Runnable() {
			@Override
			public void run() {
				SendMsg("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
				SendMsg("start data transfer task!!!");
				SendMsg("starting send and recv @@endPointOut is:"+endPointOut+"\n@@endPointIn is:"+endPointIn[0]);
				int recvLen=0,sendLen=0,countTask=0;
				taskStart=1;
				while(taskStart == 1)
				{
					recvLen = USBRecvData(sendBuffer, 64*188, 10000);
					Log.d(TAG ,"Received:"+recvLen+" Buffer[0]="+recvBuffer[0]);
					countTask++;
					if(countTask > 100){
						Log.d(TAG ,"Received:"+recvLen+" Buffer[0]="+recvBuffer[0]);
					}
					/*
					sendBuffer[0] = (byte) 0xfe;
					sendBuffer[1] = 0x00;
					sendBuffer[2] = 0x10;
					sendBuffer[3] = 0x00;
					sendLen = USBSendData(sendBuffer, 4, 10000);
					recvLen = USBRecvData(recvBuffer, 4, 10000);					
					taskStart = 0;
					SendMsg("had recv Data !recv[0]="+recvBuffer[0]);
					SendMsg("had recv Data !recv[1]="+recvBuffer[1]);
					SendMsg("had recv Data !recv[2]="+recvBuffer[2]);
					SendMsg("had recv Data !recv[3]="+recvBuffer[3]);
					countTask++;
					if(countTask > 100){
						countTask = 0;
						SendMsg("had recv:"+recvLen+" Data !recv[1]="+recvBuffer[1]+" 100 times");
						SendMsg("had send:"+sendLen+" Data !recv[1]="+sendBuffer[1]+" 100 times");
					}
					try {
						Thread.currentThread();
						Thread.sleep(10);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					*/
				}
				SendMsg("taskStatus == 0 data transfer quit");
				SendMsg("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
			}
		});
       }
	private int InitUsbInterface(UsbDevice usbDevice) {
		usbConnection = mUsbManager.openDevice(usbDevice);
		// UsbInterface usbInterface = usbDevice.getInterface(0);
		if (!usbConnection.claimInterface(usbDevice.getInterface(0), true)) {
			LogMsg("claimInterface error");
			return 0;
		}

		UsbInterface usbInterface = usbDevice.getInterface(0);
		int j = 0,k = 0;
		for (int i = 0; i < usbInterface.getEndpointCount(); i++) {
			LogMsg("Get point number" + i + "type is:"
					+ usbInterface.getEndpoint(i).getType());
			if (usbInterface.getEndpoint(i).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
				if (usbInterface.getEndpoint(i).getDirection() == UsbConstants.USB_DIR_IN){
					endPointIn[j++] = usbInterface.getEndpoint(i);
					SendMsg("endPointIn: "+usbInterface.getEndpoint(i));
				}
				else{
					endPointOut[k++] = usbInterface.getEndpoint(i);
					SendMsg("endPointOut: "+usbInterface.getEndpoint(i));
				}
			}

			if (usbInterface.getEndpoint(i).getType() == UsbConstants.USB_ENDPOINT_XFER_INT) {
				endPointINT = usbInterface.getEndpoint(i);
			}
		}
		if (endPointIn[0] != null || endPointOut[0] != null || endPointINT != null) {
			USBInitOk = 1;
			LogMsg("GET SMIT USB DEVICE");
		} else {
			USBInitOk = 0;
			LogMsg("CAN NOT GET SMIT DEVICE");
		}
		return USBInitOk;
	}

	public int USBSendData(byte SendBuf[], int SendBufLen, int timeout) {
		int ret;
		if (USBInitOk == 1 && endPointOut[0] != null) {
			ret = usbConnection.bulkTransfer(endPointOut[0], SendBuf, SendBufLen,
					timeout);
			return ret;
		} else {
			SendMsg("NOT FOUND SMIT USB DEVICE");
			return -1;
		}
	}

	public int USBRecvData(byte Recv[], int RecvBufLen, int timeout) {
		int ret = 100;
		if (USBInitOk == 1 && endPointIn[0] != null) {
			ret = usbConnection.bulkTransfer(endPointIn[0], Recv, RecvBufLen, timeout);
			return ret;
		} else {
			SendMsg("NOT FOUND SMIT USB DEVICE");
			return -1;
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	private void SendMsg(String str){
		Log.d(TAG, str);
		Message msg = msgHandler.obtainMessage();
		msg.what = USB_HANDLE_MSG;
		Bundle data = new Bundle();
		data.putString("msg", str);
		msg.setData(data);
		msg.sendToTarget();
	}
	
	private void LogMsg(String msg) {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss",Locale.US);     
		Date curDate = new Date(System.currentTimeMillis());//获取当前时间     
		String timeString = formatter.format(curDate); 
		msgText.setText(timeString + "  "+msg + "\n" + msgText.getText());
		Log.d(TAG, msg);
	}
}